
package com.eportal.service;

import com.alibaba.fastjson.JSONObject;
import com.framework.jqgrid.Page;
import com.framework.jqgrid.PageEntity;
import com.eportal.util.CommonUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.common.Mapper;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
@Service
public abstract class BaseServiceImpl<T> implements BaseService<T> {

	protected static final String SUCCESS = "success";
	protected static final String ERROR = "error";
	protected Logger logger = Logger.getLogger(BaseServiceImpl.class);

	@Autowired
	protected Mapper<T> mapper;


	@Transactional
	public JSONObject save(T entity) {
		JSONObject json = new JSONObject();
		try {
			if(this.mapper.insertSelective(entity)==1){
				json.put("result",0);
				json.put("msg","操作成功");
				json.put("data",1);
				return json;
			}else {
				json.put("result",1);
				json.put("msg","未知异常，更新数据不成功");
				json.put("data",0);
				return json;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			logger.error("---update error---", e);

			json.put("result",1);
			json.put("msg","服务器异常："+e.getMessage());
			json.put("data", null);
			return json;
		}
	}

	@Transactional
	public String delete(Object key) {
		int result = 0;
		try {
			result = this.mapper.deleteByPrimaryKey(key);
		} catch (Exception e) {
			logger.error("---del error---", e);
		}
		return result > 0 ? SUCCESS : ERROR;
	}

	@Transactional
	public JSONObject update(T entity) {
		JSONObject json = new JSONObject();
		try {
			if(this.mapper.updateByPrimaryKeySelective(entity)==1){
				json.put("result",0);
				json.put("msg","操作成功");
				json.put("data",1);
				return json;
			}else {
				json.put("result",1);
				json.put("msg","未知异常，更新数据不成功");
				json.put("data",0);
				return json;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			logger.error("---update error---", e);

			json.put("result", 1);
			json.put("msg", "服务器异常：" + e.getMessage());
			json.put("data", null);
			return json;
		}
	}

	@Transactional
	public String batchDelete(Object ids[]) {
		try {
			for (int i = 0; i < ids.length; i++) {
				delete(ids[i]);
			}
		} catch (Exception e) {
			logger.error("---batch error---", e);
			return ERROR;
		}
		return SUCCESS;
	}

	public T findByPrimaryKey(Object key) {
		try {
			return this.mapper.selectByPrimaryKey(key);
		} catch (Exception e) {
			logger.error("---find error---", e);
			throw new MyBatisSystemException(e);
		}
	}

	/**
	 * 查询单个对象：如果多条记录则会抛出异常
	 *
	 * @param entity
	 * @return
	 */
	public T findByObject(T entity) {
		try {
			return this.mapper.selectOne(entity);
		} catch (Exception e) {
			logger.error("错误的查询,检查是否返回多个结果集!", e);
			throw new MyBatisSystemException(e);
		}
	}

	public List<T> queryExampleForList(Object example)
	{
		return this.mapper.selectByExample(example);
	}

	public List<T> queryObjectForList(String order) {
//		PageHelper.orderBy(order);
		return this.mapper.selectAll();
	}

	public List<T> queryObjectForList()
	{
		return this.mapper.selectAll();
	}

	/**
	 * 带条件查询所有
	 *
	 * @param entity
	 * @return
	 */
	public List<T> queryObjectForList(T entity)
	{
		return this.mapper.select(entity);
	}

	public PageInfo<T> queryPageForList()
	{
		return queryPageForList(null);
	}

	public PageInfo<T> queryPageForList(T entity) {
		HttpServletRequest request = CommonUtil.getHttpRequest();
		Integer pageNo = CommonUtil.valueOf(request.getParameter("pageNo"), 1);
		Integer pageSize = CommonUtil.valueOf(request.getParameter("pageSize"), 10);
		PageHelper.startPage(pageNo, pageSize);
		String orderField = camelToUnderline(request.getParameter("sort"));//驼峰命名-->下划线（对应数据库字段）
		String orderDirection = request.getParameter("order");
		if (StringUtils.isNotEmpty(orderField)) {
			PageHelper.orderBy(orderField);
			if (StringUtils.isNotEmpty(orderDirection)) {
				PageHelper.orderBy(orderField + " " + orderDirection);
			}
		}
		return new PageInfo<T>(mapper.select(entity));
	}

	public PageInfo<T> queryPageForLista(T entity,PageEntity pageEntity){

		PageHelper.startPage(pageEntity.getPageNo(), pageEntity.getPageSize());
		String orderField = camelToUnderline(pageEntity.getSort());//驼峰命名-->下划线（对应数据库字段）
		String orderDirection = pageEntity.getOrder();
		if (StringUtils.isNotEmpty(orderField)) {
			PageHelper.orderBy(orderField);
			if (StringUtils.isNotEmpty(orderDirection)) {
				PageHelper.orderBy(orderField + " " + orderDirection);
			}
		}

		return new PageInfo<>(mapper.selectByExample(entity));
	}

	/**
	 * 分页（可直接返回给前台）
	 *
	 * @param pageInfo
	 * @param pageEntity
	 * @return
	 */
	@Override
	public JSONObject buildJSONPageForWeb(PageInfo<T> pageInfo, PageEntity pageEntity) {
		JSONObject json = new JSONObject();
		try {
			json.put("result",0);
			if(pageInfo.getList().size()==0){
				json.put("msg","暂无数据");
			}else{
				json.put("msg","ok");
			}
			json.put("data",pageInfo.getList());
			Page page = new Page(pageInfo.getPrePage(),pageEntity.getPageNo(),pageInfo.getNextPage(),pageInfo.getLastPage());
			json.put("page", page);
			json.put("total",pageInfo.getTotal());
		}catch (Exception e){
			json.put("result",1);
			json.put("msg","服务器异常："+e.getMessage());
			json.put("data", null);
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		return json;
	}

	/**
	 * 构建实体（可直接返回给前台）
	 *
	 * @param object 实体对象
	 * @return
	 */
	@Override
	public JSONObject buildJSONObjectForWeb(Object object) {
		JSONObject json = new JSONObject();
		try {
			json.put("result", 0);
			json.put("msg", "ok");
			json.put("data", object);
		}catch (Exception e){
			json.put("result",1);
			json.put("msg", "服务器异常：" + e.getMessage());
			json.put("data", null);
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		return json;
	}

	/**
	 * 构建实体失败（可直接返回给前台）
	 *
	 * @param object 实体对象
	 * @return
	 */
	@Override
	public JSONObject buildErrorJSONObjectForWeb(Object object) {
		JSONObject json = new JSONObject();
		json.put("result",1);
		json.put("msg", "服务器异常:"+object);
		json.put("data", null);
		return json;
	}


	public static final char UNDERLINE='_';
	//驼峰命名-->改为下划线 如  updatedAT -->updated_at
	public static String camelToUnderline(String param){
		if (param==null||"".equals(param.trim())){
			return "";
		}
		int len=param.length();
		StringBuilder sb=new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c=param.charAt(i);
			if (Character.isUpperCase(c)){
				sb.append(UNDERLINE);
				sb.append(Character.toLowerCase(c));
			}else{
				sb.append(c);
			}
		}
		return sb.toString();
	}
	//取消下划线-->驼峰命名 如 updated_at   --> updatedAT
	public static String underlineToCamel(String param){
		if (param==null||"".equals(param.trim())){
			return "";
		}
		int len=param.length();
		StringBuilder sb=new StringBuilder(len);
		for (int i = 0; i < len; i++) {
			char c=param.charAt(i);
			if (c==UNDERLINE){
				if (++i<len){
					sb.append(Character.toUpperCase(param.charAt(i)));
				}
			}else{
				sb.append(c);
			}
		}
		return sb.toString();
	}
	public static String underlineToCamel2(String param){
		if (param==null||"".equals(param.trim())){
			return "";
		}
		StringBuilder sb=new StringBuilder(param);
		Matcher mc= Pattern.compile("_").matcher(param);
		int i=0;
		while (mc.find()){
			int position=mc.end()-(i++);
			//String.valueOf(Character.toUpperCase(sb.charAt(position)));
			sb.replace(position-1,position+1,sb.substring(position,position+1).toUpperCase());
		}
		return sb.toString();
	}

	public static void common_sort(PageEntity pageEntity){
		String orderField = camelToUnderline(pageEntity.getSort());//驼峰命名-->下划线（对应数据库字段）
		String orderDirection = pageEntity.getOrder();
		if (StringUtils.isNotEmpty(orderField)) {
			PageHelper.orderBy(orderField);
			if (StringUtils.isNotEmpty(orderDirection)) {
				PageHelper.orderBy(orderField + " " + orderDirection);
			}
		}
	}

	public Map<String,Object> getMyPageInfo(List<T> list,PageEntity pageEntity){
		Map<String,Object> resultMap = new HashMap<>();
		PageInfo<T> pageInfo = new PageInfo<>();
		Integer pageNum = list.size()%pageEntity.getPageSize()==0?list.size()/pageEntity.getPageSize():list.size()/pageEntity.getPageSize()+1;

		return resultMap;
	}

	public static void main(String[] args) {
		System.out.println(underlineToCamel("update_at"));
		System.out.println(camelToUnderline("updateAt"));

	}

	public PageInfo getPageInfo(PageInfo from,PageInfo to){
		to.setEndRow(from.getEndRow());
		to.setFirstPage(from.getFirstPage());
		to.setHasNextPage(from.isHasNextPage());
		to.setHasPreviousPage(from.isHasPreviousPage());
		to.setIsFirstPage(from.isIsFirstPage());
		to.setIsLastPage(from.isIsLastPage());
		to.setNavigatepageNums(from.getNavigatepageNums());
		to.setNextPage(from.getNextPage());
		to.setOrderBy(from.getOrderBy());
		to.setPageNum(from.getPageNum());
		to.setPages(from.getPages());
		to.setPrePage(from.getPrePage());
		to.setSize(from.getSize());
		to.setStartRow(from.getStartRow());
		to.setTotal(from.getTotal());
		return to;
	}

}
